/*
    消费者相关类的测试
*/
#include <gtest/gtest.h>
#include "../../src/server/consumer.hpp"

mq::ConsumerManager::ConsumerManagerPtr consumer_manager_ptr;
class ConsumerTest : public testing::Environment
{
public:
	virtual void SetUp() override
	{
		consumer_manager_ptr = std::make_shared<mq::ConsumerManager>();
	}

	virtual void TearDown() override
	{
		consumer_manager_ptr->clear();
	}
};

void callback(const std::string &tag, const mq::BasicProperties* properties, const std::string &body)
{
    std::cout << "callback..." << std::endl;
}

// 增加消费者测试
TEST(ConsumerTest, increaseConsumer_test)
{
    // 队列1
    consumer_manager_ptr->increaseConsumer("tag1", "queue1", true, callback);
    consumer_manager_ptr->increaseConsumer("tag2", "queue1", true, nullptr);
    consumer_manager_ptr->increaseConsumer("tag3", "queue1", true, nullptr);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue1", "tag1"), true);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue1", "tag2"), true);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue1", "tag3"), true);

    // 队列2
    consumer_manager_ptr->increaseConsumer("tag1", "queue2", true, callback);
    consumer_manager_ptr->increaseConsumer("tag2", "queue2", true, nullptr);
    consumer_manager_ptr->increaseConsumer("tag3", "queue2", true, nullptr);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue2", "tag1"), true);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue2", "tag2"), true);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue2", "tag3"), true);

    // 队列3
    consumer_manager_ptr->increaseConsumer("tag1", "queue3", true, callback);
    consumer_manager_ptr->increaseConsumer("tag2", "queue3", true, nullptr);
    consumer_manager_ptr->increaseConsumer("tag3", "queue3", true, nullptr);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue3", "tag1"), true);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue3", "tag2"), true);
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue3", "tag3"), true);
}

// 移除消费者测试
TEST(ConsumerTest, removeConsumer_test)
{
    consumer_manager_ptr->removeConsumer("queue1", "tag1");
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue1", "tag1"), false);
    
    consumer_manager_ptr->removeConsumer("queue2", "tag2");
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue2", "tag2"), false);
    
    consumer_manager_ptr->removeConsumer("queue3", "tag3");
    EXPECT_EQ(consumer_manager_ptr->hasConsumer("queue3", "tag3"), false);
}

// 选择消费者测试
TEST(ConsumerTest, choose_test)
{
    // queue1
    mq::Consumer::ConsumerPtr consumer = consumer_manager_ptr->choose("queue1");
    EXPECT_EQ(consumer->_tag, "tag2");
    EXPECT_EQ(consumer->_queue_name, "queue1");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_EQ(consumer->_callback, nullptr);
    consumer = consumer_manager_ptr->choose("queue1");
    EXPECT_EQ(consumer->_tag, "tag3");
    EXPECT_EQ(consumer->_queue_name, "queue1");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_EQ(consumer->_callback, nullptr);
    consumer = consumer_manager_ptr->choose("queue1");
    EXPECT_EQ(consumer->_tag, "tag2");
    EXPECT_EQ(consumer->_queue_name, "queue1");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_EQ(consumer->_callback, nullptr);

    // queue2
    consumer = consumer_manager_ptr->choose("queue2");
    EXPECT_EQ(consumer->_tag, "tag1");
    EXPECT_EQ(consumer->_queue_name, "queue2");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_NE(consumer->_callback, nullptr);
    consumer = consumer_manager_ptr->choose("queue2");
    EXPECT_EQ(consumer->_tag, "tag3");
    EXPECT_EQ(consumer->_queue_name, "queue2");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_EQ(consumer->_callback, nullptr);
    consumer = consumer_manager_ptr->choose("queue2");
    EXPECT_EQ(consumer->_tag, "tag1");
    EXPECT_EQ(consumer->_queue_name, "queue2");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_NE(consumer->_callback, nullptr);

    // queue3
    consumer = consumer_manager_ptr->choose("queue3");
    EXPECT_EQ(consumer->_tag, "tag1");
    EXPECT_EQ(consumer->_queue_name, "queue3");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_NE(consumer->_callback, nullptr);
    consumer = consumer_manager_ptr->choose("queue3");
    EXPECT_EQ(consumer->_tag, "tag2");
    EXPECT_EQ(consumer->_queue_name, "queue3");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_EQ(consumer->_callback, nullptr);
    consumer = consumer_manager_ptr->choose("queue3");
    EXPECT_EQ(consumer->_tag, "tag1");
    EXPECT_EQ(consumer->_queue_name, "queue3");
    EXPECT_EQ(consumer->_auto_ack, true);
    EXPECT_NE(consumer->_callback, nullptr);
}

// 销毁消费者队列测试
TEST(ConsumerTest, destroyConsumerQueue_test)
{
    consumer_manager_ptr->destroyConsumerQueue("queue1");
    EXPECT_EQ(consumer_manager_ptr->empty("queue1"), true);

    consumer_manager_ptr->destroyConsumerQueue("queue2");
    EXPECT_EQ(consumer_manager_ptr->empty("queue2"), true);

    consumer_manager_ptr->destroyConsumerQueue("queue3");
    EXPECT_EQ(consumer_manager_ptr->empty("queue3"), true);
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new ConsumerTest);
    return RUN_ALL_TESTS();
}